
#include "mlVec4.h"

namespace ml
{

	Vec4::Vec4(void)
	{
		zero();
	}
	Vec4::Vec4(const Vec4 &a)
	{
		X = a.X;
		Y = a.Y;
		Z = a.Z;
		W = a.W;
	}
	Vec4::Vec4(const Vec3 &a, float w)
	{
		X = a.X;
		Y = a.Y;
		Z = a.Z;
		W = w;
	}
	Vec4::Vec4(const Vec2 &a, float z, float w)
	{
		X = a.X;
		Y = a.Y;
		Z = z;
		W = w;
	}

	Vec4::Vec4(float x, float y, float z, float w)
	{
		X = x;
		Y = y;
		Z = z;
		W = w;
	}

	Vec4::~Vec4(void)
	{
	}

	Vec4 &Vec4::operator =(const Vec4 &a)
	{
		X = a.X;
		Y = a.Y;
		Z = a.Z;
		W = a.W;
		return *this;
	}

	bool Vec4::operator ==(const Vec4 &a) const
	{
		return X == a.X && Y == a.Y && Z == a.Z && W == a.W;
	}
	bool Vec4::operator !=(const Vec4 &a) const
	{
		return X != a.X || Y != a.Y || Z != a.Z || W != a.W;
	}
	Vec4 Vec4::operator -() const
	{
		return Vec4(-X, -Y, -Z, -W);
	}
	Vec4 Vec4::operator +(const Vec4 &a) const
	{
		return Vec4(X + a.X, Y + a.Y, Z + a.Z, W + a.W);
	}
	Vec4 Vec4::operator -(const Vec4 &a) const
	{
		return Vec4(X - a.X, Y - a.Y, Z - a.Z, W - a.W);
	}
	Vec4 Vec4::operator *(float a) const
	{
		return Vec4(a * X, a * Y, a * Z, a * W);
	}
	Vec4 Vec4::operator /(float a) const
	{
		if (a == 0) return *this;
		float ar = 1.0f / a;
		return Vec4(ar * X, ar * Y, ar * Z, ar * W);
	}
	Vec4 &Vec4::operator +=(const Vec4 &a)
	{
		X += a.X;
		Y += a.Y;
		Z += a.Z;
		W += a.W;
		return *this;
	}
	Vec4 &Vec4::operator -=(const Vec4 &a)
	{
		X -= a.X;
		Y -= a.Y;
		Z -= a.Z;
		W -= a.W;
		return *this;
	}
	Vec4 &Vec4::operator *=(float a)
	{
		X *= a;
		Y *= a;
		Z *= a;
		W *= a;
		return *this;
	}
	Vec4 &Vec4::operator /=(float a)
	{
		if (a == 0.0f) return *this;
		float ar = 1.0f / a;
		X *= ar;
		Y *= ar;
		Z *= ar;
		W *= ar;
		return *this;
	}
	float &Vec4::operator [](int i)
	{
		switch (i)
		{
		case 0:
			return X;
		case 1:
			return Y;
		case 2:
			return Z;
		case 3:
			return W;
		default:	//is this the right course of action to take
			return X;
		}
	}
	float Vec4::operator *(const Vec4 &a) const
	{
		return X * a.X + Y * a.Y + Z * a.Z + W * a.W;
	}

	float * Vec4::toFloatPtr(void) const
	{
		return (float *)this;
	}

	Vec3 Vec4::toVec3(void)
	{
		return Vec3(X, Y, Z);
	}
	Vec2 Vec4::toVec2(void)
	{
		return Vec2(X, Y);
	}

	void Vec4::normalize()
	{
		float magSq = X*X + Y*Y + Z*Z + W*W;
		if (magSq > 0.0f) // check for divide-by-zero
		{ 
			float ar = 1.0f / sqrt(magSq);
			X *= ar;
			Y *= ar;
			Z *= ar;
			W *= ar;
		}
	}
	void Vec4::zero()
	{
		X = 0.0f;
		Y = 0.0f;
		Z = 0.0f;
		W = 0.0f;
	}

}